package com.xinchuang.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xinchuang.common.KeyWordSystem;
import com.xinchuang.entity.image.ImageResult;
import com.xinchuang.entity.image.RecognitionTable;
import com.xinchuang.service.TiffUtilService;
import com.xinchuang.service.image.GDALService;
import com.xinchuang.service.image.ImageCutService;
import com.xinchuang.service.image.ImageResultService;
import com.xinchuang.service.image.RecognitionTableService;
import com.xinchuang.util.FileElseUtil;
import com.xinchuang.util.LngLatUtil;
import com.xinchuang.utils.CommonUtil;
import com.xinchuang.utils.DrawOnTiff;
import com.xinchuang.utils.ObjectUtil;
import com.xinchuang.vo.RecognitionListVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.Dataset;
import org.geotools.coverage.CoverageFactoryFinder;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridFormatFinder;
import org.geotools.gce.geotiff.GeoTiffFormat;
import org.geotools.gce.geotiff.GeoTiffReader;
import org.geotools.gce.geotiff.GeoTiffWriteParams;
import org.geotools.gce.geotiff.GeoTiffWriter;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.util.factory.Hints;
import org.opengis.coverage.grid.GridCoverageReader;
import org.opengis.coverage.grid.GridCoverageWriter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * TODO
 *
 * @author zkwczx
 * @version 1.0
 * @date 2024/7/8 14:52
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TiffUtilServiceImpl implements TiffUtilService {

    private final KeyWordSystem keyWordSystem;

    private final ImageResultService imageResultService;

    private final RecognitionTableService recognitionTableService;

    private final GDALService gdalService;

    private SnowflakeGenerator snow = new SnowflakeGenerator(0, 0);

    @Async
    @Override
    public void saveRecognition(ImageResult result, String tifPath, String imgId) {
        DrawOnTiff tiff = new DrawOnTiff();
        Dataset dataset = tiff.openFile(keyWordSystem.getFILE_URL() + tifPath);
        if (null == dataset) {
            return;
        }
        try {
            String id = snow.next().toString();
            // 读取TIF图像
            BufferedImage tifImage = ImageIO.read(new File(keyWordSystem.getFILE_URL() + tifPath));
            // 创建Graphics2D对象
            Graphics2D g2d = tifImage.createGraphics();
            // 设置字体和颜色
            Font font = new Font("Serif", Font.PLAIN, 12);
            g2d.setFont(font);
            g2d.setColor(Color.WHITE);
            List<RecognitionTable> list = recognitionTableService.lambdaQuery().eq(RecognitionTable::getRedId, imgId).list();
            for (RecognitionTable table : list) {
                if (!FileElseUtil.isDouble(table.getLon()) || !FileElseUtil.isDouble(table.getLat())) {
                    continue;
                }
                //画图
                tiff.toPosition(dataset, g2d, JSONArray.parseArray(table.getPositions()));
                //标绘文字
                tiff.toText(dataset, g2d, FileElseUtil.getStringTransitionDouble(table.getLon()), FileElseUtil.getStringTransitionDouble(table.getLat()), table.getName());
            }
            // 释放图形上下文使用的资源
            g2d.dispose();
            String path = keyWordSystem.getFILE_URL() + "/tifElse/";
            // 将修改后的图像保存为新的PNG图像
            ImageIO.write(tifImage, "PNG", new File(path + id + ".png"));
            {
                // 读取原始tif文件
                File inputFile = new File(keyWordSystem.getFILE_URL() + tifPath);
                GeoTiffReader reader = new GeoTiffReader(inputFile);
                GridCoverage2D coverage = reader.read(null);
                // 将BufferedImage转换回GridCoverage2D对象
                GridCoverageFactory factory = new GridCoverageFactory();
                ReferencedEnvelope envelope = new ReferencedEnvelope(coverage.getEnvelope());
                GridCoverage2D newCoverage = factory.create("newCoverage", tifImage, envelope);
                // 将修改后的GridCoverage2D对象保存为新的tif文件
                File outputFile = new File(path + id + "_else.tif");
                GeoTiffWriter writer = new GeoTiffWriter(outputFile);
                writer.write(newCoverage, null);
                writer.dispose();
            }
            CommonUtil.generateThumbnail(
                    path + id + ".png",
                    keyWordSystem.getFILE_URL() + "/image/thumb/" + id + "_thumb.jpg",
                    200,
                    200);
            result.setId(id);
            result.setResultUrl("/tifElse/" + id + "_else.tif");
            result.setResultThumb("/image/thumb/" + id + "_thumb.jpg");
            result.setResultRelease("/tifElse/" + id + ".png");
            imageResultService.save(result);
            log.info("识别成果保存完成");
        } catch (Exception e) {
            log.info("识别图片异常：{}", e.getMessage(), e);
        }
    }

    @Override
    public ImageResult saveEdit(ImageResult result, JSONArray array) {
        DrawOnTiff tiff = new DrawOnTiff();
        Dataset dataset = tiff.openFile(keyWordSystem.getFILE_URL() + result.getImageUrl());
        if (null == dataset) {
            return null;
        }
        try {
            String id = snow.next().toString();
            // 读取TIF图像
            BufferedImage tifImage = ImageIO.read(new File(keyWordSystem.getFILE_URL() + result.getImageUrl()));
            // 创建Graphics2D对象
            Graphics2D g2d = tifImage.createGraphics();
            for (int i = 0; i < array.size(); i++) {
                JSONObject main = array.getJSONObject(i);
                String type = main.getString("type");
                JSONObject json = main.getJSONObject("json");
                //处理点
                if ("GeoCanvasPointPoi".equals(type)) {
                    tiff.paintComponent(dataset, g2d, json.getJSONArray("position").getDouble(0), json.getJSONArray("position").getDouble(1), 5);
                } else if ("GeoPolyline".equals(type)) {
                    tiff.toLine(dataset, g2d, json.getJSONArray("positions"));
                } else if ("SMGeoRectangle".equals(type)) {
                    JSONArray position = json.getJSONArray("positions");
                    //获取坐标
                    Double minLng = 0.0;
                    Double maxLng = 0.0;
                    Double minLat = 0.0;
                    Double maxLat = 0.0;
                    minLng = position.getJSONArray(0).getDouble(0);
                    if (minLng > position.getJSONArray(1).getDouble(0)) {
                        maxLng = minLng;
                        minLng = position.getJSONArray(1).getDouble(0);
                    } else {
                        maxLng = position.getJSONArray(1).getDouble(0);
                    }
                    minLat = position.getJSONArray(0).getDouble(1);
                    if (minLat > position.getJSONArray(1).getDouble(1)) {
                        maxLat = minLat;
                        minLat = position.getJSONArray(1).getDouble(1);
                    } else {
                        maxLat = position.getJSONArray(1).getDouble(1);
                    }
                    JSONArray a = new JSONArray();
                    a.add(Arrays.asList(minLng, maxLat, 0));
                    a.add(Arrays.asList(maxLng, maxLat, 0));
                    a.add(Arrays.asList(maxLng, minLat, 0));
                    a.add(Arrays.asList(minLng, minLat, 0));
                    tiff.toClosePosition(dataset, g2d, a);
                } else if ("CzmCircleGroundPrimitive".equals(type)) {
                    tiff.paintComponent(dataset, g2d, json.getJSONArray("position").getDouble(0), json.getJSONArray("position").getDouble(1), json.getDouble("radius").intValue());
                } else if ("GeoPolygon".equals(type)) {
                    tiff.toClosePosition(dataset, g2d, json.getJSONArray("positions"));
                }  else if ("GeoDivTextPoi".equals(type)) {
                    int size = 14;
                    if (ObjectUtil.isNotEmpty(json.getDouble("fontSize"))) {
                        size = json.getDouble("fontSize").intValue();
                    }
                    tiff.toText(dataset, g2d, json.getJSONArray("position").getDouble(0), json.getJSONArray("position").getDouble(1), json.getString("text"), size);
                }  else {
                    continue;
                }
            }
            //抗锯齿效果
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            // 释放图形上下文使用的资源
            g2d.dispose();
            String path = keyWordSystem.getFILE_URL() + "/tifElse/";
            // 将修改后的图像保存为新的PNG图像
            ImageIO.write(tifImage, "PNG", new File(path + id + ".png"));
            {
                // 读取原始tif文件
                File inputFile = new File(keyWordSystem.getFILE_URL() + result.getImageUrl());
                GeoTiffReader reader = new GeoTiffReader(inputFile);
                GridCoverage2D coverage = reader.read(null);
                // 将BufferedImage转换回GridCoverage2D对象
                GridCoverageFactory factory = new GridCoverageFactory();
                ReferencedEnvelope envelope = new ReferencedEnvelope(coverage.getEnvelope());
                GridCoverage2D newCoverage = factory.create("newCoverage", tifImage, envelope);
                // 将修改后的GridCoverage2D对象保存为新的tif文件
                File outputFile = new File(path + id + "_else.tif");
                GeoTiffWriter writer = new GeoTiffWriter(outputFile);
                writer.write(newCoverage, null);
                writer.dispose();
            }
            CommonUtil.generateThumbnail(
                    path + id + ".png",
                    keyWordSystem.getFILE_URL() + "/image/thumb/" + id + "_thumb.jpg",
                    200,
                    200);
            result.setId(id);
            result.setResultUrl("/tifElse/" + id + "_else.tif");
            result.setResultThumb("/image/thumb/" + id + "_thumb.jpg");
            result.setResultRelease("/tifElse/" + id + ".png");
            String jsonUrl = keyWordSystem.getFILE_URL() + "/tifElse/" + id + ".json";
            FileUtil.writeString(array.toJSONString(), jsonUrl, "UTF-8");
            result.setPosition("/tifElse/" + id + ".json");
            return result;
        } catch (Exception e) {
            log.info("识别图片异常：{}", e.getMessage(), e);
        }
        return null;
    }

}
